function ValidateForm(validateFormOpt) {
    const self = this
    //是否开启表单验证
    this.enable = true
    //获取表单元素
    this.formElement = document.querySelector(validateFormOpt.formSelector)

    //获取所有字段的数组
    this.fields = Object.keys(validateFormOpt.fieldsOpt)

    //初始化字段配置，处理默认参数
    this.initValiFields = function () {
        this.fieldsOpt = validateFormOpt.fieldsOpt
        this.fields.forEach(function (field) {
            //如果没有错误提示，则默认加上
            if (!self.fieldsOpt[field].errorMsg) {
                self.fieldsOpt[field].errorMsg = `${field} error`
            }
            //如果没有选择器，则默认使用字段作为name选择
            if (!self.fieldsOpt[field].selector) {
                self.fieldsOpt[field].selector = `[name=${field}]`
            }
        })
    }
    //根据slector找到对应的输入字段元素
    this.getIpts = function () {
        //获取输入框元素
        this.iptEle = {}
        this.fields.forEach(function (field) {
            self.iptEle[field] = self.formElement.querySelectorAll(self.fieldsOpt[field].selector)
        })
    }

    //初始化验证结果对象
    this.initValiRes = function () {
        //以字段为键，值默认都为false表示该字段验证不通过
        this.valiRes = {}
        this.fields.forEach(function (field) {
            self.valiRes[field] = {
                pass: false,
                msg: null
            }
        })
    }

    //给所有输入框绑定onchange事件
    this.bindFieldEvent = function () {
        //通过forEach拿到所有字段
        this.fields.forEach(function (field) {
            //根据字段拿到对应的输入框
            let elements = self.iptEle[field]
            //给输入框添加onchange事件
            elements.forEach(function(element){
                element.onchange = function () {
                    //调用验证函数，验证当前字段
                    self.valiRes[field] = self.valiField(field)
                }
            })
            
        })
    }

    //验证一个字段，如果验证通过返回true,否则返回false
    this.valiField = function (field) {
        let fieldRes = this.valiRes[field]
        //如果验证关闭直接忽略
        if(!this.enable) return fieldRes
        //验证该字段的所有规则
        let rules = this.fieldsOpt[field].rules
        for (let ruleType in rules) {
            //根据验证规则获取规则验证函数
            const valiRuleFuc = this[`vali_${ruleType}`]
            //调用验证函数，结果为false或者true
            const ruleRes = valiRuleFuc(rules[ruleType],field)
            const errorMsg = this.fieldsOpt[field].errorMsg || ''
            const successMsg = this.fieldsOpt[field].successMsg || ''
            //如果出现验证不成功
            if (!ruleRes) {
                //设置验证结果为false
                fieldRes.pass = false
                //如果errorMsg为对象，且对应的验证规则键存在
                if (typeof errorMsg == 'object') {
                    fieldRes.msg = errorMsg[ruleType] ? errorMsg[ruleType] : `${field} error`
                } else {
                    fieldRes.msg = errorMsg
                }
                break
            }else{
                fieldRes.pass = true
                fieldRes.msg = successMsg
            }
        }
        this.handleFieldRes(field, fieldRes)
        return fieldRes
    }
    /*******************验证方式******************/
    //正则验证
    this.vali_reg = function (reg, field) {
        const value = self.iptEle[field][0].value
        return reg.test(value)
    }
    //值验证
    this.vali_value = function (targetValue, field) {
        const value = self.iptEle[field][0].value
        return value == targetValue
    }
    //字段值相等验证
    this.vali_equal = function (targetField, field) {
        const value = self.iptEle[field][0].value
        let targetValue = self.iptEle[targetField][0].value
        return targetValue == value
    }
    //验证必填内容
    this.vali_require = function(require,field){
        const element = self.iptEle[field][0]
        if(require){
            //如果该元素是radio或者checkbox，判断是否有被选中的输入框
            if(element.type == 'checkbox' || element.type == 'radio'){
                for(let element of self.iptEle[field]){
                    if (element.checked){
                        return true
                    }
                }
                return false
            }else{
                return !!element.value
            }
        }
        return true
    }
    //验证选项必须选择
    this.vali_checked = function(checked,field){
        if(checked){
            return self.iptEle[field][0].checked
        }
        return true
    }

    //处理字段验证结果
    this.handleFieldRes = function (field, valiRes) {
        const element = this.iptEle[field][0]
        if (valiRes.pass) {
            //如果该字段验证成功
            //优先调用字段自有回调函数
            if (typeof this.fieldsOpt[field].fieldSuccess == 'function') {
                this.fieldsOpt[field].fieldSuccess(field, valiRes.msg, element)
            } else if ( typeof validateFormOpt.fieldSuccess == 'function') {
                validateFormOpt.fieldSuccess(field, valiRes.msg, element)
            }
        } else {
            //如果该字段验证失败
            if (typeof this.fieldsOpt[field].fieldError == 'function') {
                this.fieldsOpt[field].fieldError(field, valiRes.msg, element)
            } else if (typeof validateFormOpt.fieldError == 'function') {
                validateFormOpt.fieldError(field, valiRes.msg, element)
            }
        }
    }
    //处理表单提交
    this.handleSubmit = function (validateFormOpt) {
        let submit;
        if(validateFormOpt.submitSelector){
            submit = self.formElement.querySelector(validateFormOpt.submitSelector)
        }else{
            submit = self.formElement.querySelector('button') || 
            self.formElement.querySelector('[type=submit]')
        }
        submit.addEventListener('click', function (e) {
            if(!self.enable) return
            if (self.isPass()) {
                //表单验证通过，如果有formSuccess则调用
                if (typeof validateFormOpt.formSuccess == 'function') {
                    validateFormOpt.formSuccess(self.valiRes)
                }
            } else {
                //阻止表单提交
                e.preventDefault()
                self.handleSubmitError()
                //让第一个未通过验证的字段对应的输入框获得焦点
                if (typeof validateFormOpt.formError == 'function') {
                    validateFormOpt.formError(self.valiRes)
                }
            }

        })
    }
    //处理提交时候验证错误
    this.handleSubmitError = function () {
        let noPassField
        for (let field of this.fields) {
            if (!this.valiRes[field].pass) {
                noPassField = field
                break
            }
        }
        //未通过字段输入框获取焦点
        this.iptEle[noPassField][0].focus()
        this.valiField(noPassField)
    }

    //表单所有字段验证结果
    this.isPass = function () {
        //验证结果对象添加pass属性，
        for (let field in self.valiRes) {
            let fieldRes = self.valiRes[field]
            if(!fieldRes.pass){
                return false
            }     
        }
        return true
    }


    /********************调用函数,实现数据初始化*****************************/
    //初始化字段配置
    this.initValiFields()
    //初始化字段对应的元素
    this.getIpts()
    //初始化字段验证结果
    this.initValiRes()
    //绑定事件
    this.bindFieldEvent()
    //处理提交
    this.handleSubmit(validateFormOpt)

}